package models.parsers;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.Date;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import utils.DateUtil;

public abstract class BaseExcelParser extends BaseFileParser {
    public HSSFWorkbook workbook;
    static Logger _logger = Logger.getLogger(HsbcCreditParser.class);

    public BaseExcelParser(String filename) {
        super(filename);
    }

    public BaseExcelParser(InputStream inputstream) {
        super(inputstream);
    }

    protected HSSFWorkbook readFile() throws IOException {
        _logger.info("reading file");
        return new HSSFWorkbook(getInputStream());
    }

    HSSFCell getCellAt(HSSFSheet sheet, int rowNum, int cellNum) {

        HSSFRow row = sheet.getRow(rowNum);

        return row.getCell(cellNum);
    }

    public abstract int findTransactionsHeaderRow(HSSFSheet sheet);

    public BigDecimal parseAmount(String amount) {

        DecimalFormat decimalFormatCurrency = new DecimalFormat("$#,##0.00;-$#,##0.00");
        Number parsed = null;
        try {
            parsed = decimalFormatCurrency.parse(amount);
        } catch (ParseException e) {
            DecimalFormat decimalFormat = new DecimalFormat("#,##0.00;-#,##0.00");
            try {
                parsed = decimalFormat.parse(amount);
            } catch (ParseException e1) {
                HsbcCreditParser._logger.error(e);
            }
        }
        if (parsed != null) {
            return new BigDecimal(parsed.toString());
        } else {
            return null;
        }
    }

    public Date parseDate(String date) {

        Date parsedDate = null;
        try {
            parsedDate = DateUtil.parseDate(date, "dd MMM yy");
        } catch (IllegalArgumentException e) {
            _logger.error("unable to parse date:" + date, e);
        }
        return parsedDate;
    }

    protected int findRowWithText(HSSFSheet sheet, String searchText) {
        int rows = sheet.getLastRowNum();

        for (int r = 0; r < rows; r++) {

            HSSFRow row = sheet.getRow(r);
            if (row == null) {
                continue;
            }

            int cells = row.getLastCellNum();

            for (int colIndex = 0; colIndex < cells; colIndex++) {
                HSSFCell cell = row.getCell(colIndex);

                String value = getStringValue(cell);

                if (searchText.equals(value)) {
                    return r;
                }
            }
        }
        return -1;
    }

    protected String getStringValueAt(HSSFSheet sheet, int rowNum, int cellNum) {
        HSSFCell cell = getCellAt(sheet, rowNum, cellNum);
        return getStringValue(cell);
    }

    protected String getStringValue(HSSFCell cell) {
        String value = "";
        if (cell != null) {
            switch (cell.getCellType()) {
                case HSSFCell.CELL_TYPE_STRING:
                    value = cell.getStringCellValue();
                    break;
                case HSSFCell.CELL_TYPE_NUMERIC:
                    value = String.valueOf(cell.getNumericCellValue());
                    break;
            }
        }
        return value;
    }

    protected int getIntegerAt(HSSFSheet sheet, int rowNum, int cellNum) {

        String value = getStringValueAt(sheet, rowNum, cellNum);
        if (StringUtils.isEmpty(value)) {
            return 0;
        }
        return Integer.parseInt(value);
    }

    protected Date getDateAt(HSSFSheet sheet, int rowNum, int cellNum) {
        HSSFCell cell = getCellAt(sheet, rowNum, cellNum);
        return parseDate(getStringValue(cell));
    }

    protected BigDecimal getBigDecimalAt(HSSFSheet sheet, int rowNum, int cellNum) {

        String value = getStringValueAt(sheet, rowNum, cellNum);
        return parseAmount(value);
    }
}
